#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <ncurses.h>

#include "Jeu.h"


void initialiser_Jeu( Jeu * j )
{
       
       
        int i,n,k;
       
        /* Initialisation du terrain de jeu */
       
       
        initialiser_Terrain(&( j->ter ));
       
       
        /* Initialisation du tableau de créatures */
		
       
        j->nb_creatures_dansniv = 0;
       
        j->nb_creatures = 0;
       
        j->nb_vagues = 5;
       
        j->numero_vague = 0;
       
        j->tabcrea = malloc( sizeof( Creature ) * 1);
       
        for(i=0;i<j->nb_creatures_dansniv;++i)
       
        {
               
                initialiser_Creature( &(j->tabcrea[i]) );
       
        }
       
        j->tab_nbcrea_vague = malloc( sizeof( int ) * j->nb_vagues );

        for(n=0;n<j->nb_vagues;++n)
        {
                j->tab_nbcrea_vague[n] = ((n+1) * (n+1));
        }
       
        /* Initialisation du tableau de tours */
       
       
       
        j->nb_tours = 5;
        
        j->nbtour_place = 0;
       
        j->tabtour = malloc( sizeof( Tour ) * j->nb_tours );
      
        for( k = 0; k < ( j->nb_tours ); ++k)
       
        {
                initialiser_Tour( &(j->tabtour[k]) );
       
        }
        
        /* Initialisation des parametres du joueur */
        j->PV_joueur = 20;
		
		j->Ressources = 1000;
         
         
}



void liberer_Jeu( Jeu * j )
{
       
        liberer_Terrain(&( j->ter ));
       
        free(j->tabcrea);
       
        free(j->tabtour);

}




const Terrain *jeuGetConstTerrain(const Jeu * j)
{
       
        return &(j->ter);

}


int creature_mort( const Jeu * j )
{
        int i;
        for( i = 0; i < j->nb_creatures_dansniv; ++i)
        {
                if( j->tabcrea[i].pointDeVie_Actuels > 0 )
                {
                        return 0;
                }
        }
        return 1;
}




void detecter_creature( Jeu * jeu )
{
	int i_tour,i,j,k;
	for(i_tour=0;i_tour<jeu->nb_tours;++i_tour)
	{
		if(jeu->tabtour[i_tour].disponible == 0)
		{
			for(i=jeu->tabtour[i_tour].x - 1; i<=jeu->tabtour[i_tour].x + 1; ++i)
			{
				for(j=jeu->tabtour[i_tour].y - 1;j<=jeu->tabtour[i_tour].y + 1; ++j) 
				{
					for(k=0;k<jeu->nb_creatures;++k)
					{
						if(jeu->tabcrea[k].positionX == i && jeu->tabcrea[k].positionY == j)
						{
							attaquer_creature(&(jeu->tabcrea[k]), &(jeu->tabtour[i_tour]));
							
							
							
						}
					}
				}
			}
		}
	}
}


void attaquer_creature(Creature * crea, Tour * tour)
{
	crea->pointDeVie_Actuels = crea->pointDeVie_Actuels - tour->puissance;
	if(crea->pointDeVie_Actuels == 0)
		{
				liberer_Creature(crea);
                crea->vivant = 0;
               
		}
}



void jeuEvolue( Jeu * j )
{
       
        int i;
      if(!(game_over(j)) || !(victoire(j)))
      {
              
				detecter_creature(j);
				
                for( i = 0; i < j->nb_creatures; ++i )
               
                {
						
                        if( (j->tabcrea[i]).positionX < (j->ter).dimx - 1 && terGetXY( &(j->ter), creagetConstPositionX( &(j->tabcrea[i]) ), creagetConstPositionY( &(j->tabcrea[i]) ) ) != 'B')
                       
                        {
                                if( j->tabcrea[i].vivant == 1 )
                                {
                                        avancer_creature( &(j->tabcrea[i]) );
                                }
                        }
                       
                        else
                       
                        {
                                liberer_Creature( &(j->tabcrea[i]) );
                                j->tabcrea[i].vivant = 0;
                                j->PV_joueur --;
                        }
                               
                }
               
               
                if( j->nb_creatures != j->nb_creatures_dansniv && j->tabcrea[i - 1].positionX == 1 )
                {
                        j->nb_creatures ++;
                }              
               
               
                if( creature_mort(j) )
                {
                        j->nb_creatures = 0;
                        j->nb_creatures_dansniv = 0;                    
                       
                        if(j->nb_vagues != j->numero_vague)
                        {
                               
								vague_suivante(j);
                        }
                               
                }
                
      }
                
}

void vague_suivante(Jeu *j)
{
		int k;
		free(j->tabcrea);
        j->nb_creatures = 1;
        j->nb_creatures_dansniv = j->tab_nbcrea_vague[j->numero_vague];
        j->tabcrea = malloc(sizeof(Creature)*j->tab_nbcrea_vague[j->numero_vague]);            
        for(k=0; k<j->nb_creatures_dansniv;++k)
        {
                initialiser_Creature(&(j->tabcrea[k]));
        }
        j->numero_vague ++;
}

int terPositionTourValide2(Jeu *j, int x , int y)
{
	int i;
		for(i=0; i<j->nb_tours;i++)
		{
				if(x == j->tabtour[i].x && y == j->tabtour[i].y)
					{	
							return 0;
					}
		}
		
		return 1;
}


void placer_Tour( Jeu * j, int x, int y)
{
	
						if( terPositionTourValide2(j,x,y) && terPositionTourValide(&(j->ter),x,y))
						{	
							if(j->nbtour_place != j->nb_tours && j->tabtour[j->nbtour_place].cout <= j->Ressources)
							{
									j->tabtour[j->nbtour_place].x = x;
									j->tabtour[j->nbtour_place].y = y;
									j->tabtour[j->nbtour_place].disponible = 0;
									j->nbtour_place ++;
									j->nbtour_disponible = j->nb_tours - j->nbtour_place;
									
							}
						}
					
		
						
}

void enlever_tour( Jeu * j, int x, int y)
{
	int i_tour;
	for(i_tour=0;i_tour<j->nb_tours;++i_tour)
	{
		if(j->tabtour[i_tour].x == x && j->tabtour[i_tour].y == y)
		{
			j->tabtour[i_tour].disponible = 1;
			j->nbtour_place --;
		}
		
	}
}

void jeuActionClavier( Jeu * j,const char touche, int x, int y )
{
	switch( touche )
	{
		case 't' :
					placer_Tour( j, x, y);
				break;
				
		case 'x':
				enlever_tour(j,x,y);
				break;
	}	
}


int game_over( const Jeu * jeu )
{
	if( jeu->PV_joueur <= 0 )
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

int victoire( const Jeu * jeu)
{
	if( jeu->numero_vague == jeu->nb_vagues && (creature_mort(jeu))  )
	{
		return 1;
	}
	else
	{
		return 0;
	}
}







